<?php
/**
 * Created by PhpStorm.
 * User: wuchao
 * Date: 2020/5/19
 * Time: 15:38
 */

namespace app\api\model;

use \Exception as E;
use think\facade\Db;
use \think\response\Json;
use app\common\Image;

class OrderModel
{
    private static $_table = 'order'; // 用户表
    private static $_goods = 'goods';//商品表
    private static $_userTable = 'user'; // 用户表
    private static $_configTable = 'eb_config'; // 配置表
    private static $_adminTable = 'admin'; // 管理员表
    /**生成订单
     * @param array $input
     * @return Json
     */
    public static function NewOrder($input)
    {
        $flag = false;
        try {
            $user = Db::table(self::$_userTable)->field('is_adopt,pid,name,phone,role_type')->where('id', $input['uid'])->find();//下单用户数据
            if ($user['is_adopt'] != 1) return jsonFail('暂未通过审核或审核未通过，不能生成订单');
            $goodsData = json_decode($input['goodsData'], true);//转换商品数据
            if (!$goodsData) return jsonFail('商品数据错误');
            $map = [
                ['admin_id', '=', $input['admin_id']],
                ['name', 'in', 'ratio_proportion,order_time_slot']
            ];
            $config = Db::table(self::$_configTable)->field('name,group_concat(value) as value')->where($map)->group('name')->select()->toArray();
            if (!$config) return jsonFail('系统配置错误');
            $config = array_column($config,'value', 'name');
            if (!isset($config['ratio_proportion'])) return jsonFail('缺少系统反比');
            if (!isset($config['order_time_slot'])) return jsonFail('缺少系统下单时间');
            $time = date('H:i');
            $orderTimeSlots = explode(',', $config['order_time_slot']);
            $inTime = false;
            foreach ($orderTimeSlots as $v) {
                $orderTime = explode('-', $v);
                if ($time >= $orderTime[0] && $time <= $orderTime[1]) {
                    $inTime = true;
                }
            }
            if ($inTime == false) return jsonFail('不在下单时间范围内，无法下单');
            $adminTable = self::$_adminTable;
            $sql = "(select pid,percent,level from {$adminTable} where id = {$input['admin_id']} and `level` = 2)
            union
            (select pid,percent,level from {$adminTable} where id = ((select pid from {$adminTable} where id = {$input['admin_id']} and `level` = 2)) and `level` = 1)
            union
            (select pid,percent,level from {$adminTable} where id = ((select pid from {$adminTable} where id = ((select pid from {$adminTable} where id = {$input['admin_id']} and `level` = 2)) and `level` = 1)) and `level` = 0)";
            $percentArr = Db::query($sql);
            if (count($percentArr) != 3) return jsonFail('运营商配置错误');
            foreach ($percentArr as $v) {
                if ($v['level'] == 2) {
                    $driver_percent = $v;
                    continue;
                }
                if ($v['level'] == 1) {
                    $primary_percent = $v;
                    continue;
                }
                if ($v['level'] == 0) {
                    $company_percent = $v;
                    continue;
                }
            }
            $master_order_no = create_order_no();//主订单号
            $code = substr(microtime(), -6);//生成提货码
            $goods_ids = array_column($goodsData, 'goods_id');//商品规格ID
            $field = 'c.name as unit_name,c.type as unit_type,b.name as center_name,a.name,a.id,a.stock,a.status,a.image,';
            $field .= "(case 
                    when is_activity = 1 THEN act_price
                    when 1 = {$input['is_believe']} then price
                    when 0 = {$input['is_believe']} then ot_price
                    end) as price";
            $goods_data = Db::table(self::$_goods)->alias('a')
                ->join('goods_unit c', 'a.unit_id=c.id')
                ->join('organization b', 'a.center_id=b.id')
                ->where('a.id', 'in', $goods_ids)
                ->field($field)
                ->select()->toArray();
            $out_attrData = [];
            //组合商品数据库数据
            $total_back = 0;
            foreach ($goods_data as $v) {
                if ($v['status'] != 1) return jsonFail("该商品已下架,商品名：{$v['name']}");
                if (!key_exists($v['id'], $out_attrData)) {
                    $out_attrData[$v['id']] = $v;
                }
            }
            $out_goodsData = [];
            //组合商品前端数据
            foreach ($goodsData as $v) {
                if (!key_exists($v['goods_id'], $out_goodsData)) {
                    $out_goodsData[$v['goods_id']] = $v;
                }
            }
            if ($input['pay_type'] == 1 && $input['is_believe'] == 1) {//授信用户时或者余额支付时
                $is_pay = 1;
                $pay_time = time();
                $change_message = '创建订单成功，授信用户积分付款成功，等待出库！';
            } elseif ($input['pay_type'] == 1) {
                $is_pay = 1;
                $pay_time = time();
                $change_message = '创建订单成功，积分付款成功，等待出库！';
            } else if ($input['is_believe'] == 1) {//同时
                $is_pay = 1;
                $pay_time = time();
                $change_message = '授信用户创建订单成功，等待出库！';
            } else {
                $is_pay = 0;
                $pay_time = 0;
                $change_message = '订单生成，等待付款';
            }
            Db::startTrans();
            $flag = true;
            foreach ($out_goodsData as $key => $value) {
                if (bccomp($value['total'],round($value['num'] * $out_attrData[$key]['price'], 2), 2) != 0) {
                    return jsonFail('商品总价不匹配1', $value['total']);
                }
                $total_back += $value['num'] * $out_attrData[$key]['price'];
//                if ($value['num'] < $out_attrData[$key]['stock']) {//判断库存
                    $orderIns = Db::table('order')->insertGetId([
                        'group_id' => $input['group_id'],
                        'role_type' => $input['role_type'],
                        'mastr_order_no' => $master_order_no,
                        'order_no' => build_order_no(),//生成子订单号
                        'goods_data' => json_encode($out_attrData[$key]),
                        'goods_id' => $value['goods_id'],
                        'total_price' => $value['total'],
                        'pid' => $user['pid'],
                        'pid_price' => $user['pid'] != 0 ? round($value['total'] * ($config['ratio_proportion'] / 100), 2) : 0,
                        'company_price' => round($value['total'] * ($company_percent['percent'] / 100), 2),//公司反比
                        'primary_price' => round($value['total'] * ($primary_percent['percent'] / 100), 2),//一级反比
                        'driver_price' => round($value['total'] * ($driver_percent  ['percent'] / 100), 2),//司机路费
                        'num' => $value['num'],
                        'is_believe' => $input['is_believe'],
                        'user_id' => $input['uid'],
                        'address_id' => $input['addressID'],
                        'admin_id' => $input['admin_id'],
                        'center_id' => $value['center_id'],
                        'center_name' => $value['center_name'],
                        'remark' => $input['remark'],
                        'code' => $code,
                        'is_pay' => $is_pay,
                        'pay_type' => $input['pay_type'],
                        'create_time' => time(),
                        'pay_time' => $pay_time,
                    ]);
                    $red = Db::table('order_status')->insertGetId([
                        'oid' => $orderIns,
                        'change_message' => $change_message,
                        'name' => $user['name'],
                        'phone' => $user['phone'],
                        'role_type' => $user['role_type'] == 1 ? '老板' : '员工',
                        'create_time' => time(),
                    ]);
                    if ($input['pay_type'] == 1||$input['is_believe']==1) {
                        $red = Db::execute("update goods  set stock=stock- " . $value['num'] . ",ice_stock=ice_stock+{$value['num']},sales = sales+{$value['num']} where id=" . $value['goods_id']);
                    }else {
                        $red = Db::execute("update goods  set stock=stock- " . $value['num'] . ",ice_stock=ice_stock+{$value['num']} where id=" . $value['goods_id']);
                    }
                    if ($red == false) {
                        Db::rollback();
                        return jsonFail('减少库存失败', $red);
                    }
//                } else {
//                    return jsonFail('商品库存不够，商品ID：'.$value['goods_id'], $value['goods_id']);
//                }
            }
            if ($input['total'] != round($total_back, 2)) {
                Db::rollback();
                return jsonFail('商品总价不匹配2', $total_back);
            }
            if ($orderIns != 0) {
                $cart_ids = explode(',', $input['cart_id']);
                if (empty($cart_ids)) {
                    Db::rollback();
                    return jsonFail('购物车ID错误');
                }
                $res = Db::table('cart')->where('id', 'in', $cart_ids)->delete();
                if ($res != 0) {
                    if ($input['pay_type'] == 1) {
                        $dec = Db::table('user')
                            ->where('id', $input['uid'])
                            ->where('integral', '>=', $input['total'])
                            ->dec('integral', $input['total'])->update();
                        if ($dec != 0) {
                            Db::commit();
                            return jsonSuccess('余额支付成功', ['order_no' => $master_order_no]);
                        } else {
                            Db::rollback();
                            return jsonFail('余额扣款失败', $dec);
                        }
                    } else {
                        Db::commit();
                        return jsonSuccess('订单生成成功', ['order_no' => $master_order_no]);
                    }
                } else {
                    Db::rollback();
                    return jsonFail('清除购物车出错', $res);
                }
            } else {
                Db::rollback();
                return jsonFail('生成订单失败'.$orderIns, $orderIns);
            }
        } catch (E $e) {
            if ($flag == true) Db::rollback();
            return jsonFail('系统错误~', $e->getMessage());
        }
    }

    /**查看订单列表
     * @param array $input
     * @return Json
     */
    public static function OrderList($input)
    {
        $field = 'a.id,a.role_type,a.mastr_order_no,a.order_no,a.goods_id,a.total_price,a.num,a.remark,a.center_name,a.goods_data,
            a.status,a.back_reason,a.unback_reason,a.back_time,a.is_pay,a.pay_time,a.code,a.create_time,
            c.name as arrive_name,c.phone as arrive_phone,c.province,c.city,c.area,c.address
            ,d.name as company_name';
        $map[] = ['group_id', '=', $input['group_id']];
        switch ($input['status']) {
            case 'A':
                break;
            case 'B':
                $map[] = ['status', '=', 0];
                $map[] = ['is_pay', '=', 0];
                break;
            default:
                $status = explode(',', $input['status']);
                if (empty($status)) return jsonFail('状态格式错误');
                $map[] = ['status', 'in', $input['status']];
                break;
        }
        $buildSql = Db::table('order')
            ->where($map)
            ->field('mastr_order_no')
            ->group('mastr_order_no')
            ->page($input['page'], $input['limit'])
            ->order('create_time', 'desc')
            ->buildSql();
        try {
            $data = Db::table(self::$_table)->alias('a')
                ->join('goods b', 'a.goods_id=b.id')
                ->join('company_address c', 'a.address_id=c.id')
                ->join('company d', 'a.group_id=d.id')
                ->field($field)
                ->whereRaw("mastr_order_no in (select t.mastr_order_no from {$buildSql} as t)")
                ->select()->toArray();
            $NewData = self::GetRepeatValGroup($data, 'mastr_order_no');
            return jsonSuccess('获取成功', $NewData);
        } catch (E $e){
            return jsonFail('系统错误~', $e->getMessage());
        }
    }

    /**用户申请退款
     * @param array $input
     * @param $prefixUrl
     * @return Json
     */
    public static function ApplyRefund($input, $prefixUrl)
    {
        Db::startTrans();
        try {
            // 逻辑处理
            $pic = Image::uploadSingle($input['image'], 'user');
            if (!is_string($pic)) return $pic;
            $back_image = $prefixUrl . '/api/uploads/' . str_replace('\\', '/', $pic);
            $res = Db::table('order')->where('order_no', $input['order_no'])->update(['status' => -1,
                'back_image' => $back_image,
                'back_reason' => $input['back_reason'],
            ]);
            if ($res != 0) {
                Db::commit();
                return jsonSuccess('申请成功');
            } else {
                Db::rollback();
                return jsonFail('申请失败', $res);
            }
        } catch (E $e) {
            Db::rollback();
            return jsonFail('系统错误~', $e->getMessage());
        }
    }

    /**用户申请退款
     * @param array $input
     * @param $prefixUrl
     * @return Json
     */
    public static function GoodsReply($input, $prefixUrl)
    {
        Db::startTrans();
        try {
            // 逻辑处理
            if($input['image']){
                $pic = Image::uploadSingle($input['image'], 'user');
                if (!is_string($pic)) return $pic;
                $back_image = $prefixUrl . '/api/uploads/' . str_replace('\\', '/', $pic);
            }else{
                $back_image  = '';
            }
            $res = Db::table('order')->where('id', $input['oid'])->update(['status' => 5,
            ]);
            if ($res != 0) {
                $inser = Db::table('goods_reply')->insertGetId([
                    'uid'=>$input['uid'],
                    'oid'=>$input['oid'],
                    'goods_id'=>$input['goods_id'],
                    'admin_id'=>$input['admin_id'],
                    'goods_score'=>$input['goods_score'],
                    'service_score'=>$input['service_score'],
                    'comment'=>$input['comment'],
                    'pics'=>$back_image,
                    'add_time'=>time(),
                ]);
                $user = Db::table('user')->where('id',$input['uid'])->field('name,phone,role_type')->find();
                $red = Db::table('order_status')->insertGetId([
                    'oid' => $input['oid'],
                    'change_message' => '订单已评论，评论人ID：' . $input['uid'] . '， 评论人姓名：' . $user['name'] . '，评论人电话：' . $user['phone'],
                    'name' => $user['name'],
                    'phone' => $user['phone'],
                    'role_type' => $user['role_type']==1?'老板':'员工',
                    'create_time' => time(),
                ]);
                if ($inser != 0&&$red!=0) {
                    Db::commit();
                    return jsonSuccess('评论成功');
                } else {
                    Db::rollback();
                    return jsonFail('评论失败', $res);
                }
            } else {
                Db::rollback();
                return jsonFail('评论失败', $res);
            }
        } catch (E $e) {
            Db::rollback();
            return jsonFail('系统错误~', $e->getMessage());
        }

    }

    /**组合数据，相同的分类为二维，商品为三维
     * @param $arr
     * @param $keys
     * @return array|false
     */
    public static function GetRepeatValGroup($arr, $keys)
    {
        if (!is_array($arr) || !$keys) {
            return false;
        }
        $temp = array();
        foreach ($arr as $key => $val) {
//            $total_price+= $val['total_price'];
//            $temp[$val[$keys]]['id'] = $val['id'];
            $temp[$val[$keys]]['mastr_order_no'] = $val['mastr_order_no'];
            $temp[$val[$keys]]['role_type'] = $val['role_type'];
//            $temp[$val[$keys]]['center_name'] = $val['center_name'];
            $temp[$val[$keys]]['company_name'] = $val['company_name'];
            $temp[$val[$keys]]['sub_order'][] = $val;
            foreach ($temp[$val[$keys]]['sub_order'] as  &$value) {
//                unset($value['id']);
                unset($value['mastr_order_no']);
                unset($value['role_type']);
                unset($value['company_name']);
            }
        }
        return $temp;
    }
}